package main

import (
	"bytes"
	"encoding/gob"
	"errors"
	"fmt"
	"github.com/allegro/bigcache"
	"time"
)

type Cache interface {
	Set(key,value interface{})error
	Get(key interface{})(interface{},error)
}

type bCache struct {
	ca *bigcache.BigCache
}

func (c *bCache)Set(key,value interface{})error  {
	keystring,ok:=key.(string)
	if !ok{
		return errors.New("key should be string")
	}
	valueBytes,err:=serialize(value)
	if err!=nil{
		return err
	}
//	c.ca,_=bigcache.NewBigCache(bigcache.DefaultConfig(time.Minute))
	return c.ca.Set(keystring,valueBytes)
}
func (c *bCache)Get(key interface{})(interface{},error)  {
	keystring,ok:=key.(string)
	if !ok{
		return nil,errors.New("key should be string")
	}
	valueBytes,err:=c.ca.Get(keystring)
	if err!=nil{
		return nil,err
	}
	value,err:=deserialize(valueBytes)
	if err!=nil{
		return nil,err
	}
	return value,nil
}

func serialize(value interface{})([]byte,error)  {
	buf:=bytes.Buffer{}
	enc:=gob.NewEncoder(&buf)
	gob.Register(value)
	err:=enc.Encode(&value)
	if err!=nil{
		return nil,err
	}
	return buf.Bytes(),nil
}

func deserialize(valueBytes []byte)(interface{},error)  {
	var value interface{}
	buf := bytes.NewBuffer(valueBytes)
	dec := gob.NewDecoder(buf)

	err := dec.Decode(&value)
	if err != nil {
		return nil, err
	}

	return value, nil

}

type student struct {
	//bCache
	Name string
	Age int
}

func init()  {
	B.ca,_=bigcache.NewBigCache(bigcache.DefaultConfig(time.Second*3))
}
var B bCache
func main()  {
	 s:=&student{
	 	Name:"wang",
	 	Age:123,
	 }
	//b:=&bCache{}
	//b.ca,_=bigcache.NewBigCache(bigcache.DefaultConfig(time.Second*3))
	err:=B.Set("1",s)
	if err!=nil{
		fmt.Println("set",err)
	}
	v,err:=B.Get("1")
	if err!=nil{
		fmt.Println("get",err)
	}
	fmt.Println(v)
	time.Sleep(time.Second*5)
	ss:=&student{
		Name:"wanwg",
		Age:1233,
	}
	err=B.Set("2",ss)
	if err!=nil{
		fmt.Println("set",err)
	}
	vv,err:=B.Get("2")
	if err!=nil{
		fmt.Println("get",err)
	}
	fmt.Println(vv)
}